/**
 * 
 */
package demo.feed;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import demo.util.DateTimeUtils;
import demo.util.Encoding;

/**
 * @author roger.xu
 * 
 */
public class AtomSaxParser {

    private static Log log = LogFactory.getLog(AtomSaxParser.class.getName());

    private static final SAXParser SAX_PARSER = getParser();

    public static SAXParser getParser() {
        final SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = null;
        try {
            saxParser = factory.newSAXParser();
        } catch (ParserConfigurationException e) {
            log.error(e.getMessage(), e);
        } catch (SAXException e) {
            log.error(e.getMessage(), e);
        }

        return saxParser;
    }

    public static Map<String, Object> parse(final String feedUrl) throws IOException, SAXException {
        if (SAX_PARSER == null) {
            throw new SAXException("sax parser is not initialized.");
        }

        InputStream inputStream = null;

        final URL url = new URL(feedUrl);
        final URLConnection conn = url.openConnection();
        conn.setRequestProperty("User-Agent", "Mozilla/4.0");
        conn.connect();
        inputStream = conn.getInputStream();

        final Reader reader = new InputStreamReader(inputStream, Encoding.UTF8);
        final InputSource is = new InputSource(reader);
        is.setEncoding(Encoding.UTF8);

        // parse feed
        final AtomSaxContentHandler handler = new AtomSaxContentHandler();
        SAX_PARSER.parse(is, handler);

        // return result
        final Map<String, Object> feed = handler.getFeed();
        return feed;
    }

    public static Date parseDateTime(final String str) {
        Date date = null;

        // var regexp = /^([\d-]+T[\d:]+)(?:\.\d{3})?Z$/i;
        final String regex = "^([\\d-]+T[\\d:]+)(?:\\.\\d{3})?Z$";
        final Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

        final Matcher matcher = pattern.matcher(str);
        while (matcher.find()) { // find() must be called before fetch group
            if (matcher.groupCount() > 0) {
                date = DateTimeUtils.parseISODateTime(matcher.group(1)); // group index starts from 1
            }
        }

        return date;
    }

    public static String formatDate(final Date date) {
        final DateFormat formatter = new SimpleDateFormat("MMM d, yyyy HH:mm", Locale.ENGLISH);
        final String formattedDate = formatter.format(date);
        return formattedDate;
    }
}
